package br.unisinos.tga;

import java.nio.IntBuffer;

/**
 *
 * @author Unisinos
 */
public class Imagem {

    /**
     * Buffer com os pixels da imagem
     */
    private IntBuffer pixels;
    /**
     * Largura da imagem
     */
    private int largura;
    /**
     * Altura da imagem
     */
    private int altura;
    /**
     * Cor chave para considerar transparente, atualmente em 0x00ff00ff Magenta
     */
    public static final int TRANSPARENTE = 0x00ff00ff;

    /**
     * Constr�i a imagem com resolu��o informada e aloca �rea de pixels.
     *
     * @param largura
     * @param altura
     */
    public Imagem(int largura, int altura) {
        super();
        pixels = IntBuffer.allocate(largura * altura);
        this.largura = largura;
        this.altura = altura;
    }

    /**
     * Retorna o Buffer de pixels da imagem.
     *
     * @return
     */
    public IntBuffer getPixels() {
        return pixels;
    }

    /**
     * Indica novo buffer de pixels.
     *
     * @param pixels
     */
    public void setPixels(IntBuffer pixels) {
        this.pixels = pixels;
    }

    /**
     * Retorna a largura da imagem
     *
     * @return
     */
    public int getLargura() {
        return largura;
    }

    /**
     * Indica a largura da imagem
     *
     * @param largura
     */
    public void setLargura(int largura) {
        this.largura = largura;
    }

    /**
     * Retorna a altura da imagem
     *
     * @return
     */
    public int getAltura() {
        return altura;
    }

    /**
     * Indica a altura da imagem
     *
     * @param altura
     */
    public void setAltura(int altura) {
        this.altura = altura;
    }

    /**
     * Indica um pixel na posi��o determinada da imagem.
     *
     * @param x
     * @param y
     * @param argb
     */
    public void setARGB(int x, int y, int argb) {
        this.pixels.put(x + (y * this.largura), argb);
    }

    /**
     * Retorna o pixel da posi��o especificada.
     *
     * @param x
     * @param y
     * @return
     */
    public int getARGB(int x, int y) {
        return this.pixels.get(x + (y * this.largura));
    }

    /**
     * Adiciona um pixel na pr�xima posi��o com par�metros de cor separados.
     *
     * @param alpha
     * @param red
     * @param green
     * @param blue
     */
    public void setPixel(int alpha, int red, int green, int blue) {
        int pixel = 0;
        pixel = (alpha << 24) | (red << 16) | (green << 8) | blue;
        this.pixels.put(pixel);
    }

    /**
     * Adiciona um pixel na pr�xima posi��o, considerando o pixel como
     * trasparente se a cor RGB for igual � constante
     *
     * {@code Imagem.TRANSPARENTE.}
     *
     * @see br.unisinos.tga.Imagem#TRANSPARENTE
     * @param red
     * @param green
     * @param blue
     */
    public void setPixel(int red, int green, int blue) {
        int pixel = 0;
        pixel = (red << 16) | (green << 8) | blue;
        //Se n�o for a cor transparente
        if (pixel != Imagem.TRANSPARENTE) {
            pixel = pixel | 255 << 24;
        }
        this.pixels.put(pixel);
    }

    /**
     * Adiciona o pixel na pr�xima posi��o.
     *
     * @param ARGB Dados de cor do pixel, Alpha, Red, Blue, Green em cada byte
     * do int.
     */
    public void setPixel(int ARGB) {
        this.pixels.put(ARGB);
    }

    public void inverte() {
        IntBuffer novo = IntBuffer.allocate(pixels.limit());
        int length = pixels.limit() - 1;
        for (int i = 0; i <= length; i++) {
            novo.put(length - i, pixels.get(i));
        }
        pixels = novo;
    }

    public void alteraAlpha(int novoAlpha) {

        int a, r, g, b;

        for (Integer i : pixels.array()) {

            a = (i >> 24) & 0xff;
            r = (i >> 16) & 0xff;
            g = (i >> 8) & 0xff;
            b = i & 0xff;
            if (i == TRANSPARENTE) {
                this.setPixel(a, r, g, b);
            } else {
                this.setPixel(novoAlpha, r, g, b);
            }
        }
        this.getPixels().rewind();


    }

    void removeAlpha() {
        int a, r, g, b;

        for (Integer i : pixels.array()) {

            a = (i >> 24) & 0xff;
            r = (i >> 16) & 0xff;
            g = (i >> 8) & 0xff;
            b = i & 0xff;
            if (i == TRANSPARENTE) {
                this.setPixel(a, r, g, b);
            } else {
                this.setPixel(255, r, g, b);
            }
        }
        this.getPixels().rewind();


    }
}